function varargout = data_prepare(varargin)
%  __  __                            _   _       
% |  \/  |                          | | | |      
% | \  / | __ _ _ __ __ _ _   _  ___| |_| |_ ___ 
% | |\/| |/ _` | '__/ _` | | | |/ _ \ __| __/ _ \
% | |  | | (_| | | | (_| | |_| |  __/ |_| ||  __/
% |_|  |_|\__,_|_|  \__, |\__,_|\___|\__|\__\___|
%                      | |                       
%                      |_|                       
%  _    _       _                    _ _         
% | |  | |     (_)                  (_) |        
% | |  | |_ __  ___   _____ _ __ ___ _| |_ _   _ 
% | |  | | '_ \| \ \ / / _ \ '__/ __| | __| | | |
% | |__| | | | | |\ V /  __/ |  \__ \ | |_| |_| |
%  \____/|_| |_|_| \_/ \___|_|  |___/_|\__|\__, |
%                                           __/ |
%                                          |___/ 
% 
% Last Modified by Corey Bost for Marquette University's
% Speech and Signal Processing Lab

%This file is part of the Marquette Univeristy Speech Recognition Toolkit.
%This module converts the user's data from .wav to .mfc for use with the
% HTK tools. One way of doing this is to use the categories you created;
% check the "use categories" checkbox and then highlight all the categories
% you need to have converted. Once done, you can click the convert button
% and your .wav files will be converted to .mfc. If you don't want to use
% categories, you can browse to your data, but make sure that
% your data is separated into folders by category first. 

%Copyright 2009


% DATA_PREPARE M-file for data_prepare.fig
%      DATA_PREPARE, by itself, creates a new DATA_PREPARE or raises the existing
%      singleton*.
%
%      H = DATA_PREPARE returns the handle to a new DATA_PREPARE or the handle to
%      the existing singleton*.
%
%      DATA_PREPARE('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in DATA_PREPARE.M with the given input arguments.
%
%      DATA_PREPARE('Property','Value',...) creates a new DATA_PREPARE or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before data_prepare_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to data_prepare_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to module_help data_prepare

% Last Modified by GUIDE v2.5 14-Aug-2009 11:12:37

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @data_prepare_OpeningFcn, ...
                   'gui_OutputFcn',  @data_prepare_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before data_prepare is made visible.
function data_prepare_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to data_prepare (see VARARGIN)

% Choose default command line output for data_prepare
handles.output = hObject;
global main_dir; 
if isnumeric(main_dir), main_dir = strrep(which('data_prepare_OpeningFcn'),'\data_prepare.m','');end
% Update handles structure
guidata(hObject, handles);
%addpath('HTK');
set(gcf,'CloseRequestFcn',@my_closefcn);

% UIWAIT makes data_prepare wait for user response (see UIRESUME)
% uiwait(handles.figure1);

%User defined close function
function my_closefcn(hObject, eventdata, handles, varargin)
global main_dir;
cd(main_dir);
delete(gcf);
htk_tools

% --- Outputs from this function are returned to the command line.
function varargout = data_prepare_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in browse.
function browse_Callback(hObject, eventdata, handles)
% hObject    handle to browse (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%Browse button code. When clicked, the user selects a directory
%and the file path is assigned to location. If the user selects something
%the convert button is turned to enabled. If cancel is pushed without
%selecting a directory, the convert button is disabled.
location = uigetdir();
if location ~= 0
    set(handles.text1,'string',location);
    set(handles.convert,'enable','on');
    set(handles.checkbox2,'value',0);
    set(handles.listbox1,'enable','off');
else
    set(handles.convert,'enable','off');
    set(handles.text1,'string','Please Choose the Directory that Contains Your Data.');
end


% --- Executes on button press in convert.
function convert_Callback(hObject, eventdata, handles)
% hObject    handle to convert (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global main_dir;
%The module cannot convert the data without the config file, so we must
%check to make sure that it exists first.
if exist([main_dir '/Data/config'],'file') == 2
    data_convert(hObject, eventdata, handles)
else
    h = errordlg('Please make the Config file first!','Error!');
    uiwait(h);
    delete(gcf);
    config;
end

function data_convert(hObject, eventdata, handles)
%If checkbox 2 is selected, the user will be using categories instead of
%the directory chosen.
global main_dir;
global cats_used;
if exist([main_dir '/Data/Result_allcalltype/cats_used.mat'])==2
    load([main_dir '/Data/Result_allcalltype/cats_used.mat']);
end
use_cats = get(handles.checkbox2,'value');
run_flag = 1;
if ~(get(handles.checkbox2,'value'))
    location = get(handles.text1,'string');
    run_flag = test_for_run(location);
    %strrep must be used to change the direction of the slash. When this is
    %written to a batch file later, the ' \ ' is read as another command
    %instead of as a file path.
    location = strrep(location, '\','/');
    if run_flag
        file_dir=dir(location);
        for i=1:length(file_dir)-2
            calltype{i}=file_dir(i+2).name;
        end
    end
else
    %If the user selected to use categories instead
    cats = get(handles.listbox1,'string');
    calltype = cats(get(handles.listbox1,'value'));
    temp_cats_used = get(handles.listbox1,'value');
    if length(cats_used) ~= length(temp_cats_used)
        run_flag = 0;
        use_cats = 0;
    elseif cats_used ~= temp_cats_used
        run_flag = 0;
        use_cats = 0;
    end
    
end
% Construct grammer file
if run_flag | use_cats
    fid=fopen('Data/gram','w');
    fprintf(fid,'$calltype=');
    count=0;
    for i=1:length(calltype)
        count=count+1;
        if(count==length(calltype))
            fprintf(fid,['\t' calltype{length(calltype)} ';\n']);
        else
            fprintf(fid,['\t' calltype{i} '|\n']);
        end
    end
    fprintf(fid,'\n(SENT-END $calltype SENT-END)\n');
    fclose(fid);
end

% ============= Script file ==========
if run_flag | use_cats
    fid=fopen([main_dir '/Data/codewords.scp'],'w');
    if (exist([main_dir '/Data/Data_exp/MFC'],'dir')~=7)
        mkdir([main_dir '/Data/Data_exp/MFC']);
    end
    if (exist([main_dir '/Data/Data_exp/MFC'],'dir')==7)
        rmdir([main_dir '/Data/Data_exp/MFC'],'s');
        mkdir([main_dir '/Data/Data_exp/MFC']);
    end
    if (exist([main_dir '/Data/Result_allcalltype'],'dir')~=7)
        mkdir([main_dir '/Data/Result_allcalltype']);
    end
    for k=1:length(calltype)
        if ~(get(handles.checkbox2,'value'))
            files_eachtype=dir([location '/' calltype{k} ]);
            mkdir([main_dir '/Data/Data_exp/MFC/' calltype{k}]);
            for j=1:length(files_eachtype)-2
                fprintf(fid,['"' location '/' calltype{k} '/' files_eachtype(j+2).name '"\t']);
                fprintf(fid,['"Data_exp/MFC/' calltype{k} '/' calltype{k} '_' num2str(j) '.mfc "\n']);
            end
        elseif exist([main_dir '/Data/Categories/' calltype{k} '.category'],'file')==2
            fidz = fopen(['Data/Categories/' calltype{k} '.category']);
            while ~feof(fidz)
                test = textscan(fidz,'%q');
            end
            fclose(fidz);
            files_eachtype = test{1};
            mkdir([main_dir '/Data/Data_exp/MFC/' calltype{k}]);
            for j=1:length(files_eachtype)
                fprintf(fid,['"' files_eachtype{j} '"\t']);
                fprintf(fid,['"Data_exp/MFC/' calltype{k} '/' calltype{k} '_' num2str(j) '.mfc "\n']);
            end
        else
            errordlg(['The category "' calltype{k} '" does not have any files '...
                'associated with it. Please use the Create Category module to do '...
                'this, or select a different category.']);  return;
        end
    end
    fclose(fid);
end

% =========== Model List ================
% Define phone models
if run_flag | use_cats
    fid=fopen([main_dir '/Data/model.list'],'w');
    for i=1:length(calltype)
        fprintf(fid,[calltype{i} '\n']);
    end
    fprintf(fid, 'sil \n');
    fclose(fid);
end
% ===== Construct Dictionary file ===============
if run_flag | use_cats
    fid = fopen([main_dir '/Data/dict'],'w');
    fprintf(fid, 'SENT-START []   sil\n');
    fprintf(fid, 'SENT-END []   sil\n');
    for i =1:length(calltype)
        fprintf(fid,[calltype{i} '\t']);
        fprintf(fid,[calltype{i} '\n']);
    end
    fclose(fid);
end
% % ====== Data prepare  batchfile============
if run_flag | use_cats
    fid=fopen([main_dir '/Data/dataprep.bat'],'w+');
    if (get(handles.checkbox1,'value'))
        fprintf(fid, 'HParse gram wdnet \n');
        fprintf(fid, 'HCopy -T 1 -C config -S codewords.scp \n');
    else
        fprintf(fid, 'HParse gram wdnet \n');
        fprintf(fid, 'HCopy -C config -S codewords.scp \n');
    end
    status=fclose(fid);
    msgbox('We are currently converting your data, please wait. =)','Converting');
    cd('Data');
    dos('dataprep.bat');
    msgbox('Your files have now been prepared, please enjoy them responsibly.','Complete!');
    cd('..');
end
if ~run_flag
    warndlg(['You have set up your sound directory incorrectly.'...
        'For more information, please read the tutorial.'...
        'If you are using categories, please make sure you'...
        ' have selected the same categories as your label file.'],'Danger!');
end


% --- Executes on button press in checkbox1.
function checkbox1_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox1


% --------------------------------------------------------------------
function file_menu_Callback(hObject, eventdata, handles)
% hObject    handle to file_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function help_Callback(hObject, eventdata, handles)
% hObject    handle to module_help (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function exit_Callback(hObject, eventdata, handles)
% hObject    handle to exit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
my_closefcn(hObject,eventdata,handles)


% --------------------------------------------------------------------
function module_help_Callback(hObject, eventdata, handles)
% hObject    handle to module_help (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%{
helpdlg(sprintf(['Use the browse button to select the same'...
    ' main folder with your data that was used to create the'...
    ' master label file.\n\nThe "Show Trace" checkbox, if checked,'...
    ' will output to the Matlab command window what the HTK tools'...
    ' are doing at each point in time.']));
%} 
help_launch('dataprep');

% --------------------------------------------------------------------
function about_us_Callback(hObject, eventdata, handles)
% hObject    handle to about_us (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
about_us


% --- Executes on button press in checkbox2.
function checkbox2_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%When the categories checkbox is selected the list box is loaded with the
%list of categories from the Master_Cat file. The convert button is then
%enabled if any categories are found. Only categories highlighted in the
%listbox will have the files associated with it convert though.
if get(hObject,'Value')
    fid = fopen('Data/Categories/Master_Cat.category');
    while ~feof(fid)
        test = textscan(fid,'%q');
    end
    fclose(fid);
    master = test{1};
    set(handles.listbox1,'string',master);
    set(handles.listbox1,'enable','on');
    set(handles.convert,'enable','on');
    set(handles.text1,'string','Data Location');
else
    set(handles.convert,'enable','off');
    set(handles.listbox1,'enable','off');
end
% Hint: get(hObject,'Value') returns toggle state of checkbox2


% --- Executes on selection change in listbox1.
function listbox1_Callback(hObject, eventdata, handles)
% hObject    handle to listbox1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns listbox1 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from listbox1


% --- Executes during object creation, after setting all properties.
function listbox1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to listbox1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: listbox controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
set(hObject,'Max',2);
